#!/usr/bin/env bash

# Script that runs ReactOS through SPICE
# License: CC0

# Requirements:
#   - qemu
#   - qemu-kvm or libvirt
#   - spice-gtk (provides spicy binary)
#   - spice-vdagent (optional, for auto mouse capture, mouse movement
#     improvements)
#   - cdrtools or libisofs or libisofs6, libisofs1 etc. or search with "isofs"
#     if those are not in repo (optional, to share files to ReactOS from host)

cd $(dirname $0)

[ -z "$(command -v qemu-system-$(uname -m))" ] && echo "qemu-system-$(uname -m) binary not found. Please install qemu and qemu-kvm or libvirt" && exit 111
[ -z "$(command -v spicy)" ] && echo 'spicy binary not found. Please install spice-client-gtk, spice-gtk or search repo for spice' && exit 121
[ ! -f 'reactos.iso' ] && echo 'Please put the ReactOS boot ISO as reactos.iso' && exit 122
[ ! -f 'reactos.img' ] && echo 'Please create a QEMU supported disk image as reactos.img. e.g. qemu-img create -f qcow2 reactos.img 4G' && exit 123

# SPICE host
SPICE_HOST='127.0.0.1'
# SPICE port
SPICE_PORT=5929
# QEMU PID is stored on this file with -pidfile param
QEMU_PID_FILE='/tmp/reactos-spice-qemu-pid.txt'
# How much RAM to allow ReactOS to use. e.g. 1300M for 1300mb, 4G for 4gb
RAM_AMOUNT=2G

qemu_args=(
	# RAM
	-m ${RAM_AMOUNT}
	# Enable KVM
	-enable-kvm
	# Network
	-net nic,model=ne2k_pci -net user
	# Audio
	-audiodev driver=pa,id=pa1,server=`pactl info | grep 'Server String' | awk '{print $3}'` -device AC97,audiodev=pa1
	# USB redirection - for 3 devices
	-device ich9-usb-ehci1,id=usb
	-device ich9-usb-uhci1,masterbus=usb.0,firstport=0,multifunction=on
	-device ich9-usb-uhci2,masterbus=usb.0,firstport=2
	-device ich9-usb-uhci3,masterbus=usb.0,firstport=4
	-chardev spicevmc,name=usbredir,id=usbredirchardev1 -device usb-redir,chardev=usbredirchardev1,id=usbredirdev1
	-chardev spicevmc,name=usbredir,id=usbredirchardev2 -device usb-redir,chardev=usbredirchardev2,id=usbredirdev2
	-chardev spicevmc,name=usbredir,id=usbredirchardev3 -device usb-redir,chardev=usbredirchardev3,id=usbredirdev3
	# ReactOS CD image
	-cdrom reactos.iso \
	# Disk image
	-hda reactos.img \
	# SPICE related
	-vga qxl -spice port=${SPICE_PORT},addr=${SPICE_HOST},disable-ticketing=on -usbdevice tablet
	-device virtio-serial-pci
	-device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0
	-chardev spicevmc,id=spicechannel0,name=vdagent
	# Let the script run as is after QEMU has started successfully.
	-daemonize
	# -daemonize doesn't return PID with $!. So we need to store the PID in a file.
	-pidfile "${QEMU_PID_FILE}"
	)

# Create share CD ROM ISO image to share files with ReactOS
[ ! -d _share ] && mkdir _share
if [ -n "$(command -v mkisofs)" ] && [ "$(stat -t _share)" != "$(cat _share_stat)" ]; then # if anything inside _share changed, create iso
	[ -f _share.iso ] && rm _share.iso
	if [ "$(ls -A _share)" ]; then
		mkisofs -iso-level 4 -J -l -D -N -joliet-long -untranslated-filenames -V "SHARE" -o _share.iso _share
		[ "$?" != '0' ] && echo 'ISO creation failed!' && rm _share.iso &>/dev/null && exit 1
	fi
	stat -t _share > _share_stat
fi
[ -f _share.iso ] && qemu_args+=(-drive file=_share.iso,media=cdrom)

# Run the QEMU command
qemu-system-$(uname -m) "${qemu_args[@]}"

[ "$?" -gt 0 ] && echo 'QEMU failed to start. Please check previous messages. Exiting...' && exit 131 # in case QEMU exits due to error

# Get QEMU PID from -pidfile file set previously
qemu_pid=$(cat "${QEMU_PID_FILE}" 2>/dev/null)

# Run spicy SPICE viewer
echo "QEMU is running on pid ${qemu_pid}..."
spicy --title 'ReactOS' -h "${SPICE_HOST}" -p "${SPICE_PORT}"

# When spice window is closed...
echo "Killing QEMU on pid ${qemu_pid}..."
kill -9 ${qemu_pid} && rm "${QEMU_PID_FILE}"
[ "$?" -eq 0 ] && echo 'Killed QEMU successfully. Exiting...'
